#include "global_header.h"
#include "node.h"
#include "link_network.h"

#include <iostream>

#define	__RANDOM_MAX	6

using namespace std;

/**
  * Absolute value for the float datatype.
  * @param i is floating point number.
  * @author Paul Tagliamonte
  */
float absv( float i ) {
    if (i < 0)
        return -i;
    else
        return i;
}
/**
  * Generate a random integer. Function max defined in __RANDOM_MAX
  * @author Paul Tagliamonte
  */
int getRand() {
	int random = rand() % __RANDOM_MAX + 1;
	return random;
}

/**
  * Generate a random integer. Function max defined in __RANDOM_MAX, excluding passed int.
  * @param ex is an int that can not be returned by this functon.
  * @author Paul Tagliamonte
  */
int getRandExclude( int ex ) {
	int random = rand() % __RANDOM_MAX + 1;
	if ( random == ex  ) {
		return getRandExclude( ex );
	}
	return random;
}

/**
  * Main Function. The Babies are made here.
  * @author Paul Tagliamonte
  */

int main() {

	int x = 200;
	int y = 200;

	srand( time(NULL) );

	node nodeArray[x][y];

	for ( int ix = 0; x > ix; ++ix ) {
		for ( int iy = 0; x > iy; ++iy ) {
			nodeArray[ix][iy].setStatus( getRand() );
		}
	}

	linkNetwork foo;

	for ( int ix = 0; ix < x; ++ix ) {
		for ( int iy = 0; iy < y - 1; ++iy ) {
			foo.link( ix, iy, ix, iy + 1 );
		}
	}
	for ( int ix = 0; ix < x - 1; ++ix ) {
		for ( int iy = 0; iy < y; ++iy ) {
			foo.link( ix, iy, ix + 1, iy );
		}
	}


// main action here
	bool loop = true;
	int thrsh = 0;
	int tempstat;
	float temphypostat;

	while ( loop ) {
		bool below = false;
		float global = 0;
		float global_vote_total = 0;

		for ( int ix = 0; x > ix; ++ix ) {
			for ( int iy = 0; y > iy; ++iy ) {
				if ( nodeArray[ix][iy].getHypoStatus() < thrsh ) {
					tempstat = nodeArray[ix][iy].getStatus();
					nodeArray[ix][iy].setStatus( getRandExclude( tempstat ) );
				}
				nodeArray[ix][iy].resetHypo( );
			}
		}


		for ( int ix = 0; ix < x; ++ix ) {
			for ( int iy = 0; iy < y; ++iy ) {
				nodeArray[ix][iy].setWeight( foo.getWeight( ix, iy ) );
//				cout << nodeArray[ix][iy].getWeight() << ", " << nodeArray[ix][iy].getStatus() << "\t\t";
			}
//			cout << "\n";
		}
//		cout << "\nHYPO --------------------------------- \n\n";
		for ( int ix = 0; ix < x; ++ix ) {
			for ( int iy = 0; iy < y - 1; ++iy ) {
				if ( nodeArray[ix][iy].getStatus() == nodeArray[ix][iy + 1].getStatus() ) {
					nodeArray[ix][iy].rateHypo( - nodeArray[ix][iy + 1].getWeight() );
					nodeArray[ix][iy + 1].rateHypo( - nodeArray[ix][iy].getWeight() );
				}
				if ( nodeArray[ix][iy].getHypoStatus() < thrsh ) {
					below = true;
				}
			}
		}
	
		for ( int ix = 0; ix < x - 1; ++ix ) {
			for ( int iy = 0; iy < y; ++iy ) {
				if ( nodeArray[ix][iy].getStatus() == nodeArray[ix + 1][iy].getStatus() ) {
					nodeArray[ix][iy].rateHypo( - nodeArray[ix + 1][iy].getWeight() );
					nodeArray[ix + 1][iy].rateHypo( - nodeArray[ix][iy].getWeight() );
				}
				if ( nodeArray[ix][iy].getHypoStatus() < thrsh ) {
					below = true;
				}
			}
		}
	
		for ( int ix = 0; ix < x; ++ix ) {
			for ( int iy = 0; iy < y; ++iy ) {	
				nodeArray[ix][iy].setWeight( foo.getWeight( ix, iy ) );
				global = global + nodeArray[ix][iy].getHypoStatus();
				global_vote_total = global_vote_total + nodeArray[ix][iy].getWeight();
				temphypostat = nodeArray[ix][iy].getHypoStatus();
				if ( temphypostat != 0 ) {
					cout << temphypostat << "\t";
				} else {
					cout << " " << "\t";
				}
			}
			cout << "\n";
		}

		global = global ;

		 cout << "Global Anger " << ( absv(global) / global_vote_total ) * 100 << "% \n";
		 cout << "\n\n";

//		 usleep( 800000 );

		if ( ! below ) {
			loop = false;
				cout << "\n\n";
				for ( int ix = 0; ix < x; ++ix ) {
					for ( int iy = 0; iy < y; ++iy ) {	
						cout << nodeArray[ix][iy].getStatus() << "\t";
					}
				cout << "\n";
			}
		}
	}
}
